package cn.caplike.demo.repository.java.concurrency.threadpool;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * Description: 利用 {@link ThreadPoolExecutor} 实现自动执行<br>
 * Ref: https://www.cnblogs.com/leeying/archive/2014/06/09/3778114.html
 *
 * @author LiKe
 * @date 2020-03-20 12:34:36
 */
public class DemoThreadPoolExecutor01 {
    private static List<ArrayBlockingQueue<Task>> queueList = new ArrayList<>();

    public static void main(String[] args) throws InterruptedException {
        // 初始化10个容量, 总共20. 阻塞队列中可以存10个, 所以当有超过20个线程进来的时候就被被 RejectedExecutionHandler 处理
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                10,
                20,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(10),
                new ThreadFactory() {
                    private int idx;

                    @Override
                    public Thread newThread(Runnable r) {
                        return new Thread(r, "Thread-" + (idx++));
                    }
                },
                new RejectedExecutionHandler() {
                    @Override
                    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                        System.err.println(r.toString() + "is rejected!");
                    }
                }
        );
        for (int idx = 0; idx < 1; idx++) {
            ArrayBlockingQueue<Task> queue = new ArrayBlockingQueue<>(10);
            queueList.add(queue);
            threadPoolExecutor.submit(new TaskWorkThread(queue));
        }

        /*
         * 生产者：按一定速度往阻塞队列里放入线程任务
         */
        while (true) {
            Thread.sleep(1000);

            int randomIdx = /*ThreadLocalRandom.current().nextInt(0, 10)*/0;
            System.out.println("生产端 - 放入队列 " + randomIdx + "：" + "task-" + randomIdx + "；队列容量：" + queueList.get(randomIdx).size());

            Task randomTask = new Task("task-" + ThreadLocalRandom.current().nextInt(0, 10));
            queueList.get(randomIdx).put(randomTask);
        }
    }
}

/**
 * Description: 任务
 *
 * @author LiKe
 * @date 2020-03-20 10:06:48
 */
class Task {
    private String taskName;

    public Task(String taskName) {
        this.taskName = taskName;
    }

    public String getTaskName() {
        return taskName;
    }

    public void setTaskName(String taskName) {
        this.taskName = taskName;
    }
}

/**
 * Description: 任务工作线程
 *
 * @author LiKe
 * @date 2020-03-20 10:07:09
 */
class TaskWorkThread implements Callable<Boolean> {
    private ArrayBlockingQueue<Task> queue;

    public TaskWorkThread(ArrayBlockingQueue<Task> queue) {
        this.queue = queue;
    }

    @Override
    public Boolean call() throws Exception {
        try {
            while (true) {
                Task task = queue.take();
                System.out.println("消费端 - 队列容量：" + queue.size() + "；获取到任务，准备执行：" + task.getTaskName());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Boolean.TRUE;
    }
}
